package Hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.junit.*;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;

/**
 * 客户端代码常用套路:
 * 1、获取一个客户端对象*
 * 2、执行相关的操作命令
 * 3、关闭资源
 * HDFS zookeeper
 */
public class Hdfs {
    private FileSystem fs;

    @Before
    public void init() throws URISyntaxException, IOException, InterruptedException {
        //1、获取一个客户端对象
        URI uri = new URI("hdfs://192.168.130.130:9000");
        Configuration configuration = new Configuration();
        String user = "root";
        fs = FileSystem.get(uri,configuration,user);
    }
    @After
    public void close() throws IOException {
        //3、关闭资源
        fs.close();
    }
    /**
     * 递归新建文件夹操作mkdir（）
     */
    @Test
    public void testMkdir() throws IOException {
        // 2 创建一个文件夹
        fs.mkdirs(new Path( "/testHDFSClient"));
    }
    @Test
    public void testPut() throws IOException {
        // 2 上传操作
        /*
          参数解读：
          1、表示上传完删除元数据--等于移动操作
          2、如果HDFS上已存在该文件名的文件，是否允许覆盖
          3、要上传的本地路径
          4、要上传到的HDFS上的路径
          参数优先级
          hdfs-default.xml => hdfs-site.xml=> 在项目资源目录下的配置文件 => 代码里面的配置
         */
        fs.copyFromLocalFile(false,false,new Path("./test.txt"),new Path("/testHDFSClient/text.txt"));
    }
    @Test
    public void testGet() throws IOException {
        // 2 下载操作
        /*
          参数解读：
          1、表示下载完删除元数据--等于移动操作
          2、要下载的HDFS路径
          3、要保存的本地路径
          4、是否开启本地校验--因为数据传输过程中可能出现数据丢失，使用CRC用以校验
          ↑参数为false时表示开启校验，为true时表示不开启
          参数优先级
          hdfs-default.xml => hdfs-site.xml=> 在项目资源目录下的配置文件 => 代码里面的配置
         */
        fs.copyToLocalFile(false,new Path("/testHDFSClient/text.txt"),new Path("./testFromHdfs.txt"),true);
    }
    @Test
    public void testRmdir() throws IOException {
        // 2 删除操作
        //参数二：表示是否递归删除
        fs.delete(new Path("/testHDFSClient/递归创建文件夹"),false);
    }
    @Test
    public void testMv() throws IOException {
        // 2 移动和重命名操作
        fs.rename(new Path("/testHDFSClient/text.txt"),new Path("/TEST.txt"));
    }
    @Test
    public void testCat() throws IOException {
        // 2 获取文件详情 cat
        RemoteIterator<LocatedFileStatus> locatedFileStatusRemoteIterator = fs.listFiles(new Path("/"),true);
        while (locatedFileStatusRemoteIterator.hasNext()) {
            //返回的是LocatedFileStatus类型的List迭代器，需要遍历输出
            LocatedFileStatus fileStatus = locatedFileStatusRemoteIterator.next();

            System.out.println(fileStatus.toString());

            System.out.println("==========" + fileStatus.getPath()+"=========");
            System.out.println( fileStatus.getPermission());
            System.out.println( fileStatus.getGroup());
            System.out.println(fileStatus.getOwner());
            System.out.println( fileStatus.getLen());
            System.out.println( fileStatus.getModificationTime());
            System.out.println( fileStatus.getBlockSize());
            System.out.println( fileStatus.getPath().getName());
            System.out.println(fileStatus.getReplication());
            BlockLocation[] blockLocations = fileStatus.getBlockLocations();
            System.out.println(Arrays.toString(blockLocations));

        }
    }
    @Test
    public void testFiletype() throws IOException {
        // 2 获取文件信息详情：是否是目录？是否是文件
        FileStatus[] listFiles = fs.listStatus(new Path("/"));
        for (FileStatus status : listFiles){
            if (status.isFile()) {
                System.out.println("文件" +status.getPath().getName());
            } else if (status.isDirectory()) {
                System.out.println("目录" +status.getPath().getName());
            }else {
                System.out.println("数据错误!!!");
            }
        }

    }

}
